﻿#ifndef __REACTOR_WIN32_H__
#define __REACTOR_WIN32_H__

#include "Common.h"

#ifdef SUPPORT_NET

#ifdef WIN32

#include "IReactor.h"
#include "Singleton.h"
#include "Thread.h"
#include "SwappingList.h"

#include <map>
#include <list>

namespace sky
{
#define POLLING_INTERVAL 1

    /**
    @name : 反应器 (Reactor)
    @brief: 反应器就是等待多个事件然后调用相应的处理程序的这么一个装置
            Windows下用WaitForMultipleObjects实现
    @warning: 注意:
            1.添加/删除事件需要注意多线程加锁
            2.支持多于64个事件的监听,多于64个事件时使用轮询方式检查事件
    */
    class Reactor_Win32 : public IReactor, public IEventHandler, public SingletonEx<Reactor_Win32>
    {

    public:
        Reactor_Win32();

        virtual ~Reactor_Win32();

    public:
    //////////////////////////IReactor//////////////////////////////////////////
        /**
         * @brief 填加要监听的事件
         * 
         * @param event : 事件句柄
         * @return true : 注册成功
         * @return false 已达到最大事件个数 或 该事件不存在
         */
        virtual bool AddEvent(HANDLE event);


        /**
         * @brief 移除要监听的事件 
         * 
         * @param evetn 事件句柄
         */
        virtual void RemoveEvent(HANDLE event);

        /**
         * @brief 注册一个事件(一个事件处理器可以对应多个事件，一个事件可以对应多个处理器) 
         * 
         * @param event 事件句柄
         * @param handler 事件处理器
         * @return true 注册成功
         * @return false 已经达到最大事件个数 或 该事件不存在
         */
        virtual bool RegisterEventHandler(HANDLE event, IEventHandler * handler);
        
        /**
         * @brief 取消一个事件处理器 (该事件处理器不处理该事件，但是这个事件继续监听，只有调用RemoveEvent才不再监听事件)
         * 
         * @param event 事件句柄
         * @param handler 事件处理程序
         */
        virtual void UnRegisterEventHandler(HANDLE event, IEventHandler * handler);

        /**
         * @brief 等待事件触发并分派
         * @param wait 等待的毫秒数
         * @return 等待的过程中是否出错
         */
        virtual bool HandleEvents(DWORD wait);

        /**
         * @brief 循环等待/分配事件
         * 
         * @return true 
         * @return false 
         */
        virtual bool HandleEventsLoop();

        /**
         * @brief 通知退出
         * 
         */
        virtual void notifyStop();

        /**
         * @brief 通知反应堆线程退出 这些函数都是多线程安全的
         * 
         */
        virtual void NotifyExit();

        /**
         * @brief 
         * 
         */
        virtual void Release();


    //////////////////////////IEventHandler//////////////////////////////////////////

        /**
         * @brief 处理处理器自身的操作事件，用来做多线程同步 
         * 
         * @param event 
         */
        virtual void OnEvent(HANDLE event);


    protected:
        // 真正的处理函数，这里已经到了反应堆自己的线程，没有多线程同步的问题
        bool AddEventAux(HANDLE event);
        void RemoveEventAux(HANDLE event);
        bool RegisterEventHandlerAux(HANDLE event, IEventHandler * handler);
        void UnRegisterEventHandlerAux(HANDLE event, IEventHandler * handler);
        void NotifyExitAux();

    protected:
        typedef std::list<IEventHandler *> HANDLER_LIST;
        typedef std::map<HANDLE, HANDLER_LIST> HANDLERS_MAP;

        HANDLE * m_EventHandles;        // 待监听的事件数组
        DWORD   m_dwEventsNum;          // 事件个数（已有事件个数）
        DWORD   m_dwArrayCapability;    // 数组容量 (可容纳事件个数)
        HANDLERS_MAP m_HandlersMap;     // 事件处理器列表

        HANDLE m_hSelfEvent;            // 反应器自己的维护事件
        bool m_bRun;                    // 反应器的运行状态
        
        // 任务
        struct REACTOR_TASK
        {
            // 任务操作类型
            enum
            {
                REACTOR_ADD = 0,
                REACTOR_DELETE,
                REACTOR_REGISTER,
                REACTOR_UNREGISTER,
                REACTOR_EXIT,
            };

            int     type;       // 操纵类型
            HANDLE  event;      // 事件
            IEventHandler * handler; // 事件处理器
        };

        SwappingList<REACTOR_TASK> m_TaskLisk;      // 任务列表(其他线程加入的待处理任务)

    };

} // namespace sky



#endif // WIN32



#endif // SUPPORT_NET


#endif // __REACTOR_WIN32_H__